#include "stdafx.h"

Tank::Tank(const std::wstring & name, double x, double y, int dir, int life)
{
	this->name = name;
	this->x = x;
	this->y = y;
	this->direction = dir;
	this->life = life;
	this->maxlife = life;
	//load pictures
	for (wchar_t i = '1'; i <= '4'; i++)
	{
		std::wstring temp = L"img\\" + name + i + L".png";
		picSet[i - '1'] = ImageMgr::getInstance()->getImageFromName(temp);
	}

	for (int i = 0; i < 4; i++)
	{
		width = picSet[i]->GetWidth();
		height = picSet[i]->GetHeight();
		if (width > 0 && height > 0)
		{
			break;
		}
	}
	
}

Tank::~Tank()
{
}

bool Tank::collide(Point pt)
{
	if (pt.X >= x - width / 2 && pt.X <= x + width / 2 && pt.Y >= y - height / 2 && pt.Y <= y + height / 2)
	{
		return true;
	}
	else
	{
		return false;
	}
}

void Tank::powerby(int delta)
{
	power += delta;
	power = min(power, 3);
	power = max(power, 0);
}

bool Tank::collide(Rect rc)
{
	int l = rc.GetLeft();
	int r = rc.GetRight();
	int t = rc.GetTop();
	int b = rc.GetBottom();

	double w = width / 2;
	double h = height / 2;

	return !(l < x - w && r < x - w || l > x + w && r > x + w || t < y - h && b < y - h || t > y + h && b > y + h);
}

void Tank::draw(Graphics * graphics)
{
	graphics->DrawImage(picSet[direction - 1], (int)x - width / 2, (int)y - height / 2);
	graphics->FillRectangle(&green, x - width / 2, y - height / 2 - 15, 1.0*life / maxlife*60, 5);
	graphics->DrawRectangle(&border, x - width / 2, y - height / 2 - 15, 60, 5);
}

void Tank::move(int deltax, int deltay)
{
	if (deltax > 0 && deltay == 0)
	{
		direction = DIR_RIGHT;
	}
	else if (deltax < 0 && deltay == 0)
	{
		direction = DIR_LEFT;
	}
	else if (deltax == 0 && deltay > 0)
	{
		direction = DIR_DOWN;
	}
	else if (deltax == 0 && deltay < 0)
	{
		direction = DIR_UP;
	}

	x += deltax;
	y += deltay;
}

int Tank::bleed(int amount)
{
	life -= amount;

	return life;
}

int Tank::getLife()
{
	return life;
}

Rect Tank::getRect()
{
	return Rect(x - width / 2, y - height / 2, width, height);
}

void Tank::changeDir(int direction)
{
	this->direction = direction;
}

Point Tank::getPoint()
{
	return { (int)x,(int)y };
}

//void Tank::launch(const std::wstring & name, int v, const std::wstring & sname, int lifespan)
//{
//	Bullet * b = nullptr;
//
//	switch (direction)
//	{
//	case DIR_UP:
//		b = BulletMgr::getInstance()->create(name, 0, -v, x, y - 30, sname, lifespan);
//		break;
//	case DIR_DOWN:
//		b = BulletMgr::getInstance()->create(name, 0, v, x, y + 30, sname, lifespan);
//		break;
//	case DIR_LEFT:
//		b = BulletMgr::getInstance()->create(name, -v, 0, x - 30, y, sname, lifespan);
//		break;
//	case DIR_RIGHT:
//		b = BulletMgr::getInstance()->create(name, v, 0, x + 30, y, sname, lifespan);
//		break;
//	}
//
//	b->setPowerGrade(power);
//}

//HeroTank::HeroTank(const std::wstring & name, double x, double y, int dir, int life) :Tank(name, x, y, dir, life)
//{
//}
//
//HeroTank::~HeroTank()
//{
//}

//EnemyTank::EnemyTank(const std::wstring & name, double x, double y, int dir, int v, int life, const std::wstring & bname, const tagBullet & bullet)
//	:Tank(name, x, y, dir, life), v(v), bullet(bullet), bname(bname)
//{
//}

EnemyTank::EnemyTank(const tagEnemy & enemy, double x, double y)
	: Tank(enemy.picname, x, y, enemy.direction, enemy.life), info(enemy)
{
	s = EStrategyMgr::getInstance()->get(enemy.sname);
	vx = info.v;
}

EnemyTank::~EnemyTank()
{
	AnimationMgr::getInstance()->create(L"blast3", 9, 0.2, (int)x, (int)y);
}

void EnemyTank::update(double dtime)
{
	s->idea(x, y, dtime, time, vx, vy, direction, width, height);

	/*switch (direction)
	{
	case DIR_UP:
		y -= dtime*info.v;
		break;
	case DIR_DOWN:
		y += dtime*info.v;
		break;
	case DIR_LEFT:
		x -= dtime*info.v;
		break;
	case DIR_RIGHT:
		x += dtime*info.v;
		break;
	}*/

	time += dtime;
	if (time >= info.shootinterval)
	{
		launch();
		time -= info.shootinterval;
	}

	/*if (Map::getInstance()->collide(getRect()) || Game::getInstance()->getHero()->collide(getRect()))
	{
		switch (direction)
		{
		case DIR_UP:
			y += dtime*info.v;
			break;
		case DIR_DOWN:
			y -= dtime*info.v;
			break;
		case DIR_LEFT:
			x += dtime*info.v;
			break;
		case DIR_RIGHT:
			x -= dtime*info.v;
			break;
		}
		changeDir(rand() % 4 + 1);
	}*/
}

void EnemyTank::launch()
{
	int bx, by;
	int bvx, bvy;

	switch (direction)
	{
	case DIR_UP:
		bx = x;
		by = y - height / 2;
		bvx = 0;
		bvy = -info.bulletInfo.v;
		break;
	case DIR_DOWN:
		bx = x;
		by = y + height / 2;
		bvx = 0;
		bvy = info.bulletInfo.v;
		break;
	case DIR_LEFT:
		bx = x - width / 2;
		by = y;
		bvx = -info.bulletInfo.v;
		bvy = 0;
		break;
	case DIR_RIGHT:
		bx = x + width / 2;
		by = y;
		bvx = info.bulletInfo.v;
		bvy = 0;
		break;
	}
	Bullet * b = BulletMgr::getInstance()->create(L"EnemyBullet", info.bulletInfo, bx, by, bvx, bvy);
}

//void EnemyTank::launch(const std::wstring & name, int v)
//{
//	switch (direction)
//	{
//	case DIR_UP:
//		EnemyBulletMgr::getInstance()->create(name, 0, -v, x, y - 30);
//		break;
//	case DIR_DOWN:
//		EnemyBulletMgr::getInstance()->create(name, 0, v, x, y + 30);
//		break;
//	case DIR_LEFT:
//		EnemyBulletMgr::getInstance()->create(name, -v, 0, x - 30, y);
//		break;
//	case DIR_RIGHT:
//		EnemyBulletMgr::getInstance()->create(name, v, 0, x + 30, y);
//		break;
//	}
//}

HeroTank::HeroTank(const std::wstring & name, double x, double y, int dir, int life)
	:Tank(name, x, y, dir, life)
{
}

HeroTank::~HeroTank()
{
}

//void HeroTank::launchBomb(int v, const std::wstring & sname, int lifespan)
//{
//	if (bomb > 0)
//	{
//
//	}
//}

int HeroTank::getBomb()
{
	return bomb;
}

void HeroTank::bombBy(int count)
{
	bomb += count;
	if (bomb < 0)
	{
		bomb = 0;
	}
}

void HeroTank::launch(const std::wstring & bname, const tagBullet & bullet)
{
	int bx, by;
	int bvx, bvy;

	switch (direction)
	{
	case DIR_UP:
		bx = x;
		by = y - height / 2;
		bvx = 0;
		bvy = -bullet.v;
		break;
	case DIR_DOWN:
		bx = x;
		by = y + height / 2;
		bvx = 0;
		bvy = bullet.v;
		break;
	case DIR_LEFT:
		bx = x - width / 2;
		by = y;
		bvx = -bullet.v;
		bvy = 0;
		break;
	case DIR_RIGHT:
		bx = x + width / 2;
		by = y;
		bvx = bullet.v;
		bvy = 0;
		break;
	}

	BulletMgr::getInstance()->create(bname, bullet, bx, by, bvx, bvy);
}

void HeroTank::update(double dtime)
{
	if (GetAsyncKeyState(VK_LEFT) < 0)
	{
		move(-dtime*v, 0);
		if (Map::getInstance()->collide(getRect()) || EnemyMgr::getInstance()->collide(getRect()))
		{
			move(dtime*v, 0);
			changeDir(DIR_LEFT);
		}
	}
	if (GetAsyncKeyState(VK_RIGHT) < 0)
	{
		move(dtime*v, 0);
		if (Map::getInstance()->collide(getRect()) || EnemyMgr::getInstance()->collide(getRect()))
		{
			move(-dtime*v, 0);
			changeDir(DIR_RIGHT);
		}
	}
	if (GetAsyncKeyState(VK_UP) < 0)
	{
		move(0, -dtime*v);
		if (Map::getInstance()->collide(getRect()) || EnemyMgr::getInstance()->collide(getRect()))
		{
			move(0, dtime*v);
			changeDir(DIR_UP);
		}
	}
	if (GetAsyncKeyState(VK_DOWN) < 0)
	{
		move(0, dtime*v);
		if (Map::getInstance()->collide(getRect()) || EnemyMgr::getInstance()->collide(getRect()))
		{
			move(0, -dtime*v);
			changeDir(DIR_DOWN);
		}
	}
}